import { NSwitch, NTag } from 'naive-ui'
import { isFunction } from '@/utils/is'
import { copyToClipboard, dictDisplay, formatDate } from '../utils'

/**
 * table列的回显
 * @param columnValueList
 */
export function useColumnDisplay(columns, columnsAlign, pageIndex, pageSize) {
  columns.value.forEach((columnItem) => {
    const { type, align } = columnItem
    let render
    if (!columnItem.render) {
      switch (type) {
        case 'dict':
          render = dictDisplayRender(columnItem)
          break
        case 'tag':
          render = tagDisplayRender(columnItem)
          break
        case 'link':
          render = linkDisplayRender(columnItem)
          break
        case 'switch':
          render = switchDisplayRender(columnItem)
          break
        case 'date':
          render = dateDisplayRender(columnItem)
          break
        case 'index':
          render = indexDisplayRender(columnItem)
          break
        default:
          render = defaultDisplayRender(columnItem)
      }
    } else if (isFunction(columnItem.render)) {
      render = proRender(columnItem)
    }
    columnItem['align'] = align || columnsAlign
    columnItem['render'] = render
  })

  function proRender(columnItem) {
    const { key, displayValue, render } = columnItem
    return (row, index) => {
      const value = isFunction(displayValue)
        ? displayValue(row, index)
        : row[key]
      collectDisplayValue(row, key, value)
      return render(row, index)
    }
  }

  function dictDisplayRender(columnItem) {
    const { key, displayValue, dictOptions, valueCode, labelCode, dictCode } =
      columnItem
    const dictData = dictCode ? useDictData(dictCode) : null

    return (row, index) => {
      const { optionItem, displayValue: _displayValue } = dictDisplay(
        dictData ? dictData.value : dictOptions,
        row[key],
        valueCode,
        labelCode
      )
      const { props = {}, click } = optionItem
      const style = optionItem.cssClass
        ? DICT_COLOR_STYLE[optionItem.listClass]
        : props.style
      const value = isFunction(displayValue)
        ? displayValue(row, index)
        : _displayValue
      collectDisplayValue(row, key, value)

      return h(
        'span',
        {
          ...props,
          style,
          onClick: () => {
            if (isFunction(click)) {
              click(optionItem, row, index)
            } else {
              copyToClipboard(value)
            }
          }
        },
        {
          default: () => filterValue(value)
        }
      )
    }
  }

  function tagDisplayRender(columnItem) {
    const { key, displayValue, dictOptions, valueCode, labelCode, dictCode } =
      columnItem
    const dictData = dictCode ? useDictData(dictCode) : null

    return (row, index) => {
      const { optionItem, displayValue: _displayValue } = dictDisplay(
        dictData ? dictData.value : dictOptions,
        row[key],
        valueCode,
        labelCode
      )
      const { props = {}, click, type } = optionItem
      const value = isFunction(displayValue)
        ? displayValue(row, index)
        : _displayValue
      collectDisplayValue(row, key, value)

      return h(
        NTag,
        {
          type: optionItem.listClass || type,
          ...props,
          onClick: () => isFunction(click) && click(optionItem, row, index)
        },
        { default: () => filterValue(value) }
      )
    }
  }

  function switchDisplayRender(columnItem) {
    const {
      key,
      props = {},
      checkedText,
      uncheckedText,
      displayValue
    } = columnItem

    return (row, index) => {
      const value = isFunction(displayValue)
        ? displayValue(row, index)
        : row[key]
        ? checkedText
        : uncheckedText
      collectDisplayValue(row, key, value)
      return h(
        NSwitch,
        {
          value: row[key],
          rubberBand: false,
          ...props
        },
        { checked: () => checkedText, unchecked: () => uncheckedText }
      )
    }
  }

  function linkDisplayRender(columnItem) {
    const { key, props = {}, displayValue, click } = columnItem
    const { style, ...otherPorps } = props

    return (row, index) => {
      const value = isFunction(displayValue)
        ? displayValue(row, index)
        : row[key]
      collectDisplayValue(row, key, value)
      return h(
        'span',
        {
          style: {
            textDecoration: 'underline',
            color: '#3080ed',
            cursor: 'pointer',
            ...style
          },
          ...otherPorps,
          onClick: () => {
            if (isFunction(click)) {
              click(row, index)
            } else {
              copyToClipboard(value)
            }
          }
        },
        { default: () => value }
      )
    }
  }

  function dateDisplayRender(columnItem) {
    const {
      key,
      props = {},
      format = 'YYYY-MM-DD HH:mm:ss',
      displayValue,
      click
    } = columnItem
    return (row, index) => {
      const value = isFunction(displayValue)
        ? displayValue(row, index)
        : formatDate(row[key], format)
      collectDisplayValue(row, key, value)
      return h(
        'span',
        {
          ...props,
          onClick: () => {
            if (isFunction(click)) {
              click(row, index)
            } else {
              copyToClipboard(value)
            }
          }
        },
        { default: () => filterValue(value) }
      )
    }
  }

  function indexDisplayRender(_) {
    // const { page, size } = useWatchRoute()
    return (_, index) => `${index + 1 + (pageIndex.value - 1) * pageSize.value}`
  }

  function defaultDisplayRender(columnItem) {
    const { key, props = {}, displayValue, click } = columnItem
    return (row, index) => {
      const value = isFunction(displayValue)
        ? displayValue(row, index)
        : row[key]
      collectDisplayValue(row, key, value)
      return h(
        'span',
        {
          ...props,
          onClick: () => {
            if (isFunction(click)) {
              click(row, index)
            } else {
              copyToClipboard(value)
            }
          }
        },
        { default: () => filterValue(value) }
      )
    }
  }
}

/**
 * 收集回显数据
 * @param row
 * @param key
 * @param value
 */
function collectDisplayValue(row, key, value) {
  row.__displayValue__ = row.__displayValue__ ?? {}
  row.__displayValue__[key] = value
}

function filterValue(value) {
  if (value === undefined || value === null) return '--'
  return value
}

const DICT_COLOR_STYLE = {
  success: 'color: #37a05b',
  primary: 'color: #3080ed',
  warning: 'color: #eba134',
  error: 'color: #c93252',
  info: 'color: #777c82'
}
